﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;

namespace Microsoft.WowAddonStudio.TocEditor
{
	/// <summary>
	/// This user control makes it possible to edit basic metadata tags
	/// in a grid. Basic metadata 
	/// </summary>
    public partial class BasicTocMetaEditorUserControl : UserControl
	{
		#region Private members

		private readonly IMetadataManager manager;

		#endregion

		#region Lifecycle

		/// <summary>
		/// Creates instances of <see cref="BasicTocMetaEditorUserControl"/>.
		/// </summary>
		/// <param name="manager">Manages basic metadata changes.</param>
		public BasicTocMetaEditorUserControl(IMetadataManager manager)
        {
            InitializeComponent();

            if (manager == null)
                throw new ArgumentNullException("manager");

            this.manager = manager;
            this.manager.OnMetadataChanged += manager_OnMetadataChanged;
            DataBind(this.manager.GetBasicTags());
		}

		#endregion

		#region Private member functions

		/// <summary>
		/// Handles the OnMetadataChanged event of the manager control.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="Microsoft.WowAddonStudio.TocEditor.MetadataManagerEventArgs"/> instance containing the event data.</param>
		private void manager_OnMetadataChanged(object sender, MetadataManagerEventArgs e)
        {
            if(e.TagType==TagType.BASIC)
            {
                DataBind(e.Entries);
            }
        }

		/// <summary>
		/// Datas the bind.
		/// </summary>
		/// <param name="metaTags">The meta tags.</param>
        private void DataBind(IEnumerable<KeyValuePair<string, string>> metaTags)
        {
            UnsubscribeFromEvents();
            foreach (var pair in metaTags)
            {
                SetControlValue(metaTags, pair.Key);
            }
            SubscribeToEvents();
        }

		/// <summary>
		/// Datas the bind.
		/// </summary>
		/// <param name="metaTagName">Name of the meta tag.</param>
		/// <param name="metaTags">The meta tags.</param>
        private void DataBind(string metaTagName, IEnumerable<KeyValuePair<string, string>> metaTags)
        {
            UnsubscribeFromEvents();
            SetControlValue(metaTags, metaTagName);
            SubscribeToEvents();
        }

		/// <summary>
		/// Sets the control value.
		/// </summary>
		/// <param name="metaTags">The meta tags.</param>
		/// <param name="metaTagName">Name of the meta tag.</param>
        private void SetControlValue(IEnumerable<KeyValuePair<string, string>> metaTags, string metaTagName)
        {
            try
            {
                KeyValuePair<string, string> tag = metaTags.First(kvp => kvp.Key == metaTagName);

                if (metaTagName == TocTagName.Title)
                {
                    titleTextBox.Text = tag.Value;
                }
                else if (metaTagName == TocTagName.Author)
                {
                    authorTextBox.Text = tag.Value;
                }
                else if (metaTagName == TocTagName.Version)
                {
                    versionTextBox.Text = tag.Value;
                }
                else if (metaTagName == TocTagName.Interface)
                {
                    interfaceTextBox.Text = tag.Value;
                }
                else if (metaTagName == TocTagName.Notes)
                {
                    notesTextBox.Text = tag.Value;
                }
            }
            catch (InvalidOperationException)
            {
                //No matching element found
            }
        }

		/// <summary>
		/// Handles the TextChanged event of the titleTextBox control.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void titleTextBox_TextChanged(object sender, EventArgs e)
        {
            manager[TocTagName.Title] = titleTextBox.Text;
        }

		/// <summary>
		/// Handles the TextChanged event of the authorTextBox control.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void authorTextBox_TextChanged(object sender, EventArgs e)
        {
            manager[TocTagName.Author] = authorTextBox.Text;
        }

		/// <summary>
		/// Handles the TextChanged event of the versionTextBox control.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void versionTextBox_TextChanged(object sender, EventArgs e)
        {
            manager[TocTagName.Version] = versionTextBox.Text;
        }

		/// <summary>
		/// Handles the TextChanged event of the interfaceTextBox control.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void interfaceTextBox_TextChanged(object sender, EventArgs e)
        {
            manager[TocTagName.Interface] = interfaceTextBox.Text;
        }

		/// <summary>
		/// Handles the TextChanged event of the notesTextBox control.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void notesTextBox_TextChanged(object sender, EventArgs e)
        {
            manager[TocTagName.Notes] = notesTextBox.Text;
        }

		/// <summary>
		/// Unsubscribes from events.
		/// </summary>
        private void UnsubscribeFromEvents()
        {
            titleTextBox.TextChanged -= new EventHandler(titleTextBox_TextChanged);
            authorTextBox.TextChanged -= new EventHandler(authorTextBox_TextChanged);
            versionTextBox.TextChanged -= new EventHandler(versionTextBox_TextChanged);
            interfaceTextBox.TextChanged -= new EventHandler(interfaceTextBox_TextChanged);
            notesTextBox.TextChanged -= new EventHandler(notesTextBox_TextChanged);
        }

		/// <summary>
		/// Subscribes to events.
		/// </summary>
        private void SubscribeToEvents()
        {
            titleTextBox.TextChanged+=new EventHandler(titleTextBox_TextChanged);
            authorTextBox.TextChanged+=new EventHandler(authorTextBox_TextChanged);
            versionTextBox.TextChanged+=new EventHandler(versionTextBox_TextChanged);
            interfaceTextBox.TextChanged+=new EventHandler(interfaceTextBox_TextChanged);
            notesTextBox.TextChanged+=new EventHandler(notesTextBox_TextChanged);
		}
		#endregion
	}
}